<!-- StudyTree.vue -->
<script setup lang="ts">
import { api } from '@/api/api';
import { useStudyTreeStore } from '@/stores/useStudyTreeStore'; // 确保路径正确
import { validateNull } from '@/utils/validate';
import { MindMap as TinyMindMap } from '@opentiny/vue';
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router'; // 引入 useRoute
import NodeDetailsComponent from '../../components/NodeDetailsComponent.vue'; // 引入节点详细组件

// 定义接口来描述链接结构
interface Link {
  url: string;
  type: string;
  title: string;
  link: string; // 现在是必需的
}

// 定义接口描述分支节点结构
interface BranchNode {
  links: Link[];
  title: string;
  remark: string;
  status: string;
  description: string;
  branch?: BranchNode[];
}

// 定义接口用于 JSON 内容
interface JsonContentNode {
  [key: string]: BranchNode;
}

// 定义接口用于 MindMap 组件
interface MindMapNode {
  id: string;
  topic: string;
  children: MindMapNode[];
  root?: boolean; // 可选属性
}

// 初始化 mindmapData，包含 nodeData
const mindmapData = ref<{ nodeData: MindMapNode }>({
  nodeData: {
    id: 'root',
    topic: '学习树',
    root: true,
    children: [],
  },
});

// 控制 Drawer 的显示状态
const drawerVisible = ref(false);
const selectedNode = ref<{ label: string; details: Link[] }>({ label: '', details: [] });
const route = useRoute(); // 获取路由对象
const selectedAppId = ref(route.params.id); // 从路由参数获取 id

// 生成唯一 ID 的辅助函数
const generateUniqueId = (): string => {
  return `id-${Math.random().toString(36).substr(2, 9)}`;
};

// 递归解析 JSON 数据，适配 TinyMindMap 组件
const parseJsonToMindMap = (jsonContent: JsonContentNode[]): MindMapNode[] => {
  const isBranchNode = (node: any): node is BranchNode => {
    return node && typeof node === 'object' && 'title' in node;
  };

  const traverse = (nodeData: JsonContentNode | BranchNode): MindMapNode[] => {
    const nodes: MindMapNode[] = [];

    if (typeof nodeData === 'object' && nodeData !== null) {
      if (isBranchNode(nodeData)) {
        const result: MindMapNode = {
          id: generateUniqueId(),
          topic: nodeData.title || '未命名节点',
          children: [],
        };

        if (nodeData.branch && Array.isArray(nodeData.branch)) {
          nodeData.branch.forEach((childNode) => {
            const childNodes = traverse(childNode);
            result.children.push(...childNodes);
          });
        }
        if (validateNull(result.children))
          result.children = []; // 确保 children 为数组

        nodes.push(result);
      }
      else {
        for (const key in nodeData) {
          if (Object.prototype.hasOwnProperty.call(nodeData, key)) {
            const branchNode = nodeData[key];
            nodes.push(...traverse(branchNode));
          }
        }
      }
    }

    return nodes;
  };

  // 开始解析
  const parsedNodes = jsonContent.flatMap(item => traverse(item));
  // console.log('Parsed Nodes:', parsedNodes); // 调试信息
  return parsedNodes;
};

// 查找节点详细信息
const findNodeDetails = (nodeData: JsonContentNode[], targetTopic: string): BranchNode | null => {
  let result: BranchNode | null = null;

  const isBranchNode = (node: any): node is BranchNode => {
    return node && typeof node === 'object' && 'title' in node;
  };

  const traverse = (nodeData: JsonContentNode | BranchNode): void => {
    if (result)
      return;

    if (Array.isArray(nodeData)) {
      nodeData.forEach(item => traverse(item));
    }
    else if (isBranchNode(nodeData)) {
      if (nodeData.title === targetTopic) {
        result = nodeData;
        // console.log('Match found:', nodeData); // 调试信息
        return;
      }
      if (nodeData.branch && Array.isArray(nodeData.branch))
        nodeData.branch.forEach(childNode => traverse(childNode));
    }
    else {
      for (const key in nodeData) {
        if (Object.prototype.hasOwnProperty.call(nodeData, key)) {
          const branchNode = nodeData[key];
          traverse(branchNode);
        }
      }
    }
  };

  nodeData.forEach(item => traverse(item));
  return result;
};

// 点击节点时处理事件
const onNodeClick = (nodeEvent: any) => {
  const node = nodeEvent.nodeObj;

  const storedJsonContent = localStorage.getItem('jsonContent');

  if (storedJsonContent) {
    try {
      const jsonContent: JsonContentNode[] = JSON.parse(storedJsonContent);
      // console.log('解析后的 JSON 内容:', jsonContent); // 调试信息
      const nodeDetails = findNodeDetails(jsonContent, node.topic);
      // console.log('找到的节点详情:', nodeDetails); // 调试信息

      if (nodeDetails) {
        selectedNode.value = {
          label: node.topic,
          details: nodeDetails.links || [], // 查找节点资源详情
        };
        // console.log('设置 selectedNode:', selectedNode.value); // 调试信息
        drawerVisible.value = true;
        // console.log('设置 drawerVisible 为 true'); // 调试信息
      }
      else {
        console.warn('未找到对应主题的节点详情:', node.topic); // 调试信息
      }
    }
    catch (error) {
      console.error('解析存储的 JSON 内容时出错:', error);
    }
  }
};

onMounted(async () => {
  if (selectedAppId.value) {
    try {
      const response = await api.get('/java/teacher/study_tree_json/detail', { params: { id: selectedAppId.value } });
      if (!response.data || !response.data.jsonContent) {
        console.error('Invalid API response structure:', response.data);
        return;
      }

      const jsonContent: JsonContentNode[] = JSON.parse(response.data.jsonContent);
      const { setJsonContent } = useStudyTreeStore();
      setJsonContent(jsonContent);
      localStorage.setItem('jsonContent', JSON.stringify(jsonContent));

      const parsedMindMap = parseJsonToMindMap(jsonContent);
      mindmapData.value.nodeData.children = parsedMindMap;
    }
    catch (error) {
      console.error('Error fetching study tree:', error);
    }
  }
});
</script>

<template>
  <div>
    <!-- 使用 OpenTiny 的 MindMap 组件展示思维导图 -->
    <TinyMindMap
      ref="mindmap"
      v-model="mindmapData"
      class="demo-mind-map-event"
      :options="{ draggable: false, keypress: false, editable: true, toolBar: true }"
      @select-node="onNodeClick"
    />
    <!-- Drawer 显示点击的节点详情 -->
    <a-drawer
      v-model:open="drawerVisible"
      placement="right"
      width="700"
    >
      <NodeDetailsComponent
        v-if="selectedNode.label"
        :label="selectedNode.label"
        :details="selectedNode.details"
      />
    </a-drawer>
  </div>
</template>

<style scoped>
.demo-mind-map-event {
  width: 100%;
  height: 600px;
}
</style>
